﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Containing all methods to generate Reports
/// </summary>
public class Reporting
{
    /// <summary>
    /// default HTML selectors
    /// </summary>
    string first = "<ul class='report'>",
            last = "</ul>",
            before = "<li>",
            beforeOdd = "<li class='odd'>",
            after = "</li>",
            timeBefore = "<span>",
            timeAfter = "</span>";

    // example of a report made by above HTML selectors:
    //      <ul class='report'>
    //          <li class='odd'>
    //              <span>1/1/2011</span> Report item one</span>
    //          </li>
    //          <li>
    //              <span>1/1/2011</span> Report item <em>two</em></span>
    //          </li>
    //      </ul>

    /// <summary>
    /// new reporting with default parameters of HTML unordered list
    /// </summary>
    public Reporting()
    {
    }

    /// <summary>
    /// new reporting with custom HTML mark up
    /// </summary>
    /// <param name="first">HTML selector at start of report</param>
    /// <param name="last">HTML selector at the end of report</param>
    /// <param name="before">HTML selector before each item</param>
    /// <param name="after">HTML selector after each item</param>
    public Reporting(string first, string last, string before, string after)
    {
        this.first = first;
        this.last = last;
        this.before = this.beforeOdd = before;
        this.after = after;
    }

    /// <summary>
    /// new reporting with custom HTML mark up
    /// </summary>
    /// <param name="first">HTML selector at start of report</param>
    /// <param name="last">HTML selector at the end of report</param>
    /// <param name="before">HTML selector before each item</param>
    /// <param name="beforeOdd">HTML selector before odd item</param>
    /// <param name="after">HTML selector after each item</param>
    /// <param name="timeBefore">HTML selector before each time field</param>
    /// <param name="timeAfter">HTML selector after each time field</param>
    public Reporting(string first, string last, string before, string beforeOdd, string after, string timeBefore, string timeAfter)
    {
        this.first = first;
        this.last = last;
        this.before = before;
        this.beforeOdd = beforeOdd;
        this.after = after;
        this.timeBefore = timeBefore;
        this.timeAfter = timeAfter;
    }

    /// <summary>
    /// get report of a bug
    /// </summary>
    /// <param name="bugId">ID of the bug</param>
    /// <returns>HTML markup of the report</returns>
    public string GetReportBug(int bugId)
    {
        string report = first;
        var bugReports = Logging.GetLogBug(bugId);
        foreach (Log bugReportItem in bugReports)
        {
            switch ((Logging.LogEvent)bugReportItem.LogEvent)
            {
                case Logging.LogEvent.AddBug:
                    report += ReportItemWrapper(bugReportItem.Time.Value,
                        " Bug was reported by " + UserManagement.GetTheUserLink(bugReportItem.User) +
                        " with the following information " + bugReportItem.CustomMessage);
                    break;
                case Logging.LogEvent.UpdateBugInfo:
                    report += ReportItemWrapper(bugReportItem.Time.Value,
                        " Bug was updated by " + UserManagement.GetTheUserLink(bugReportItem.User) +
                        " with the following information " + bugReportItem.CustomMessage);
                    break;
                case Logging.LogEvent.SetBugStatus:
                    report += ReportItemWrapper(bugReportItem.Time.Value,
                        " Bug status was changed to <em>" + bugReportItem.CustomMessage + "</em> by " +
                        UserManagement.GetTheUserLink(bugReportItem.User));
                    break;
                case Logging.LogEvent.AssignUserToBug:
                    report += ReportItemWrapper(bugReportItem.Time.Value,
                        " Bug was assigned to " + UserManagement.GetTheUserLink(bugReportItem.User1) +
                        " by " + UserManagement.GetTheUserLink(bugReportItem.User));
                    break;
                case Logging.LogEvent.UnassignUserFromBug:
                    report += ReportItemWrapper(bugReportItem.Time.Value,
                        " Bug was unassigned from " + UserManagement.GetTheUserLink(bugReportItem.User1) +
                        " by " + UserManagement.GetTheUserLink(bugReportItem.User));
                    break;
            }
        }
        return report + after;
    }

    /// <summary>
    /// get report of a project
    /// </summary>
    /// <param name="projectId">ID of the project</param>
    /// <returns>HTML markup of the report</returns>
    public string GetReportProject(int projectId)
    {
        string report = first;
        List<Log> projectReports = Logging.GetLogProject(projectId);
        foreach (Log projectReportItem in projectReports)
        {
            switch ((Logging.LogEvent)projectReportItem.LogEvent)
            {
                case Logging.LogEvent.AddProject:
                    report += ReportItemWrapper(projectReportItem.Time.Value,
                        " Project was created by " + UserManagement.GetTheUserLink(projectReportItem.User) +
                        " with the following information " + projectReportItem.CustomMessage);
                    break;
                case Logging.LogEvent.UpdateProjectInfo:
                    report += ReportItemWrapper(projectReportItem.Time.Value,
                        " Project was updated by " + UserManagement.GetTheUserLink(projectReportItem.User) +
                        " with the following information " + projectReportItem.CustomMessage);
                    break;
                case Logging.LogEvent.SetProjectStatus:
                    report += ReportItemWrapper(projectReportItem.Time.Value,
                        " Project status was changed to <em>" + projectReportItem.CustomMessage + "</em> by " +
                        UserManagement.GetTheUserLink(projectReportItem.User));
                    break;
                case Logging.LogEvent.AssignUserToProject:
                    report += ReportItemWrapper(projectReportItem.Time.Value,
                        UserManagement.GetTheUserLink(projectReportItem.User1) +
                        " was added to project as " + EnumUtility.GetEnumNiceName((UserManagement.Role)projectReportItem.User1.Role) +
                        " by " + UserManagement.GetTheUserLink(projectReportItem.User));
                    break;
                case Logging.LogEvent.UnassignUserFromProject:
                    report += ReportItemWrapper(projectReportItem.Time.Value,
                        " Project was unassigned from " + UserManagement.GetTheUserLink(projectReportItem.User1) +
                        " by " + UserManagement.GetTheUserLink(projectReportItem.User));
                    break;
            }
        }
        return report + after;
    }

    /// <summary>
    /// get report of a user
    /// </summary>
    /// <param name="username">username of the user</param>
    /// <returns>HTML markup of the report</returns>
    public string GetReportUser(string username)
    {
        string report = first;
        List<Log> userReports = Logging.GetLogUser(username);
        foreach (Log userReportItem in userReports)
        {
            switch ((Logging.LogEvent)userReportItem.LogEvent)
            {
                case Logging.LogEvent.CreateUser:
                    report += ReportItemWrapper(userReportItem.Time.Value,
                        " User account was created with the following information " +
                        userReportItem.CustomMessage);
                    break;
                case Logging.LogEvent.UpdateUser:
                    report += ReportItemWrapper(userReportItem.Time.Value,
                        " User account was updated with the following information " +
                        userReportItem.CustomMessage);
                    break;
                case Logging.LogEvent.EnableUser:
                    report += ReportItemWrapper(userReportItem.Time.Value,
                        " User account was " + userReportItem.CustomMessage);
                    break;
            }
        }
        return report + after;
    }

    bool odd = true;

    /// <summary>
    /// wrap a report item in HTML selectors
    /// </summary>
    /// <param name="time"></param>
    /// <param name="text"></param>
    /// <returns></returns>
    private string ReportItemWrapper(DateTime time, string text)
    {
        odd = !odd;
        return odd ?
            before + timeBefore + time.ToShortTimeString() + timeAfter + text + after :
            beforeOdd + timeBefore + time.ToShortTimeString() + timeAfter + text + after;
    }
}